# -*- coding: utf-8 -*-

CIELO_TESTES_SERVER = 'https://qasecommerce.cielo.com.br/servicos/ecommwsec.do'
CIELO_PROD_SERVER = 'https://ecommerce.cbmp.com.br/servicos/ecommwsec.do'

from datetime import datetime
import httplib
import urllib
import re
from xml.dom.minidom import parse, parseString


class Pyelo():

    '''
    Metodo, provavelmente temporario, para preenchimento do dicionario de dados
    utilizado para gerar a requisicao XML.
    '''
    def preencheDados(self):
        valores = {}

        ########## DADOS DA LOJA #############
        temp = {}
        #numero de afiliacao da loja com a Cielo (max_length=20)
        temp['numero'] = '1006993069'
        #chave de acesso da loja atribuida pela Cielo (max_length=100)
        temp['chave'] = '25fbb99741c739dd84d7b06ec78c9bac718838630f30b112d033ce2e621b34f3'
        valores['dados-ec'] = temp


        ############### DADOS DO CLIENTE ################
        temp = {}
        #numero do cartao (length=16)
        temp['numero'] = '4551870000000183'
        #validade do cartao (length=6)
        temp['validade'] = '201512' #Dez 2015
        #Indicador do codigo de seguranca: 0 (nao informado), 1 (informado), 2 (ilegivel), 9 (inexistente).
        temp['indicador'] = '9'
        #Obrigatorio se indicador = 1. Para Amex, e obrigatorio e sempre possui 4 posicoes. (length=3|4)
        temp['codigo-seguranca'] = '945'
        #opcional. Nome impresso no cartao. (max_length=50)
        temp['nome-portador'] = 'Jorginho'
        valores['dados-portador'] = temp


        ############## DADOS DO PEDIDO ##################
        temp = {}
        #id do pedido na loja (max_length=20)
        temp['numero'] = '12345678901234567890'
        #valor do pedido (max_length=12)
        temp['valor'] = '1100'
        #codigo numerico da moeda na ISO 4217. Para o Real, o codigo e 986.
        temp['moeda'] = '986'
        #data e hora de envio do pedido (length=19) Exemplo: 2010-07-14T13:56:12
        temp['data-hora'] = datetime.strftime( datetime.now(), "%Y-%m-%dT%H:%M:%S" )
        #descricao do pedido. (Opcional. max_length=1024)
        temp['descricao'] = 'Uma descricao so para nao deixar em branco.'
        #Idioma do pedido: PT (portugues), EN (ingles) ou ES (espanhol).
        #Com base nessa informacao e definida a lingua a ser utilizada nas
        #telas da Cielo. Caso nao preenchido, assume-se PT.
        temp['idioma'] = 'PT'
        valores['dados-pedido'] = temp


        ############## DADOS DO PAGAMENTO ###############
        temp = {}
        #Bandeira: visa, mastercard, amex, diners, discover ou elo (em minusculo)
        temp['bandeira'] = 'visa'
        #codigo do produto: 1 (Credito a Vista), 2 (Parcelado loja), 3 (Parcelado administradora), A (Debito)
        temp['produto'] = '1'
        #numero de parcelas. Para credito a vista ou debito, utilizar 1. (max_length=3)
        temp['parcelas'] = '1'
        valores['forma-pagamento'] = temp


        ############# DADOS "EXTRAS" ####################
        #URL da pagina de retorno. E para essa tela que o fluxo sera
        #retornado ao fim da autenticacao e/ou autorizacao. (length: 1 - 1024)
        valores['url-retorno'] = 'http://testes.dev.doois.com.br/recebe'


        #Indicador de autorizacao automatica:
        #0 (nao autorizar)
        #1 (autorizar somente se autenticada)
        #2 (autorizar autenticada e nao-autenticada)
        #3 (autorizar sem passar por autenticacao e valido somente para credito)
        #Para Amex, Diners, Discover e Elo, o valor sera sempre 3.
        valores['autorizar'] = '3'

        #Define se a transacao sera automaticamente capturada caso seja autorizada.
        #'true ou 'false'
        valores['capturar'] = 'false'

        #campo livre. (0 - 128)
        valores['campo-livre'] = ''

        #Seis primeiros numeros do cartao. (length=6)
        valores['bin'] = valores['dados-portador']['numero'][:6]

        return valores


    '''
    envia o xml para comunicacao com a cielo e retorna a resposta da cielo
    ja convertida para DOM
    '''
    def enviaXml(self, xml):
        print xml
        query = urllib.urlencode({'mensagem':xml})

        f = urllib.urlopen(CIELO_TESTES_SERVER, query)

        contents = f.read()
        print '\n\n\n'+contents
        #transforma a resposta (pagina XML) em DOM
        dom = parseString( contents )
        f.close()

        return dom


    '''
    Gera a requisicao XML com os dados armazenados no dicionario "valores".
    '''
    def geraXml(self, valores):

        xml = '<?xml version="1.0" encoding="ISO-8859-1"?>\n'
        xml += '<requisicao-transacao id="1" versao="1.1.1">\n\n'

        xml += '<dados-ec>\n'
        xml += '\t<numero>'+valores['dados-ec']['numero']+'</numero>\n'
        xml += '\t<chave>'+valores['dados-ec']['chave']+'</chave>\n'
        xml += '</dados-ec>\n'

        xml += '<dados-portador>\n'
        xml += '\t<numero>' + valores['dados-portador']['numero'] + '</numero>\n'
        xml += '\t<validade>' + valores['dados-portador']['validade'] + '</validade>\n'
        xml += '\t<indicador>' + valores['dados-portador']['indicador'] + '</indicador>\n'
        xml += '\t<codigo-seguranca>' + valores['dados-portador']['codigo-seguranca'] + '</codigo-seguranca>\n'
        xml += '\t<nome-portador>' + valores['dados-portador']['nome-portador'] + '</nome-portador>\n'
        xml += '</dados-portador>\n'


        xml += '<dados-pedido>\n'
        xml += '\t<numero>' + valores['dados-pedido']['numero'] + '</numero>\n'
        xml += '\t<valor>' + valores['dados-pedido']['valor'] + '</valor>\n'
        xml += '\t<moeda>' + valores['dados-pedido']['moeda'] + '</moeda>\n'
        xml += '\t<data-hora>' + valores['dados-pedido']['data-hora'] + '</data-hora>\n'
        xml += '\t<descricao>' + valores['dados-pedido']['descricao'] + '</descricao>\n'
        xml += '\t<idioma>' + valores['dados-pedido']['idioma'] + '</idioma>\n'
        xml += '</dados-pedido>\n'


        xml += '<forma-pagamento>\n'
        xml += '\t<bandeira>' + valores['forma-pagamento']['bandeira'] + '</bandeira>\n'
        xml += '\t<produto>' + valores['forma-pagamento']['produto'] + '</produto>\n'
        xml += '\t<parcelas>' + valores['forma-pagamento']['parcelas'] + '</parcelas>\n'
        xml += '</forma-pagamento>\n\n'


        xml += '<url-retorno>' + valores['url-retorno'] + '</url-retorno>\n'
        xml += '<autorizar>' + valores['autorizar'] + '</autorizar>\n'
        xml += '<capturar>' + valores['capturar'] + '</capturar>\n'
        xml += '<campo-livre>' + valores['campo-livre'] + '</campo-livre>\n'
        xml += '<bin>' + valores['bin'] + '</bin>\n'

        xml += '</requisicao-transacao>'

        return xml


    def recValor(self, cursor, taglist):
        aux = {}
        for p in taglist:
            aux[p] = cursor.getElementsByTagName(p)[0].childNodes[0].nodeValue
        return aux


    def recErro(self, dom):
        cursor = dom.getElementsByTagName('erro')[0]
        saida = self.recValor( cursor, ['codigo', 'mensagem'] )
        print '\n\nErro: \n'+str(saida)
        return saida


    def verificaResposta(self, dom):
        try:
            cursor = dom.getElementsByTagName('transacao')[0]
            return True
        except:
            cursor = dom.getElementsByTagName('erro')[0]
            return False


    def autRecDados(self, dom):
        saida = {}
        cursor = dom.getElementsByTagName('transacao')[0]

        #saida += t.recValor( cursor, ['tid', 'pan'] )

        cursor2 = cursor.getElementsByTagName('dados-pedido')[0]
        saida['dados-pedido'] = self.recValor( cursor2, ['numero', 'valor', 'moeda', 'data-hora', 'descricao', 'idioma'] )


        cursor2 = cursor.getElementsByTagName('forma-pagamento')[0]
        saida['forma-pagamento'] = self.recValor( cursor2, ['bandeira', 'produto', 'parcelas'] )

        '''
        0    -   Criada
        1    -   Em andamento
        2    -   Autenticada
        3    -   Nao autenticada
        4    -   Autorizada ou pendente de captura
        5    -   Nao autorizada
        6    -   Capturada
        8    -   Nao capturada
        9    -   Cancelada
        10   -   Em Autenticacao'''
        saida['status'] = cursor.getElementsByTagName('status')[0].nodeValue

        cursor2 = cursor.getElementsByTagName('autenticacao')[0]
        saida['autenticacao'] = self.recValor( cursor2, ['codigo', 'mensagem', 'data-hora', 'valor', 'eci'])

        cursor2 = cursor.getElementsByTagName('autorizacao')[0]
        #temp['arp'] = cursor2.getElementsByTagName('arp')[0].nodeValue
        saida['autorizacao'] = self.recValor( cursor2, ['codigo', 'mensagem', 'data-hora', 'valor', 'lr', 'nsu'] )


        print '\n\n\n\n'+ str(saida)

        return saida




def main():

    '''
    t = Pyelo()

    #recebe os dados preenchidos
    valores = t.preencheDados()

    #Indicador de autorizacao automatica:
    #0 (nao autorizar)
    #1 (autorizar somente se autenticada)
    #2 (autorizar autenticada e nao-autenticada)
    #3 (autorizar sem passar por autenticacao e valido somente para credito)
    #Para Amex, Diners, Discover e Elo, o valor sera sempre 3.
    if valores['autorizar'] == '1':
        pass
    elif valores['autorizar'] == '2':
        pass
    elif valores['autorizar'] == '3':
        #gera a requisicao xml
        xml = t.geraXml(valores)
        #xml = xml.encode('ISO-8859-1')
        #envia a requisicao xml e recebe a resposta convertida para DOM
        dom = t.enviaXml(xml)

        #verifica se nao houve erro
        ok = t.verificaResposta(dom)
        if ok:
            #se nao houve erro: recupera os dados da transacao
            saida = t.autRecDados(dom)
        else:
            #se houve erro: recupera a mensagem de erro
            saida = t.recErro(dom)
    '''

    temp = {}
    temp['numero'] = '1006993069'
    #chave de acesso da loja atribuida pela Cielo (max_length=100)
    temp['chave'] = '25fbb99741c739dd84d7b06ec78c9bac718838630f30b112d033ce2e621b34f3'

    xml =  '<requisicao-autenticacao id="1274443086492" versao="1.0.0">'

    xml +=    '<dados-ec>'
    xml +=        '<numero>1006993069</numero>'
    xml +=        '<chave>25fbb99741c739dd84d7b06ec78c9bac718838630f30b112d033ce2e621b34f3</chave>'
    xml +=        '<nome>Loja Teste</nome>'
    xml +=        '<codigo-pais>097</codigo-pais>'
    xml +=    '</dados-ec>'

    xml +=    '<dados-portador>'
    xml +=        '<numero>4551870000000183</numero>'
    xml +=        '<validade>201501</validade>'
    xml +=        '<indicador>1</indicador>'
    xml +=        '<codigo-seguranca>585</codigo-seguranca>'
    xml +=    '</dados-portador>'

    xml +=    '<dados-pedido>'
    xml +=        '<numero>610035645</numero>'
    xml +=        '<valor>10000</valor>'
    xml +=        '<moeda>986</moeda>'
    xml +=        '<data-hora>'+datetime.strftime( datetime.now(), "%Y-%m-%dT%H:%M:%S" )+'</data-hora>'
    xml +=        '<idioma>PT</idioma>'
    xml +=    '</dados-pedido>'

    xml +=    '<forma-pagamento>'
    xml +=        '<produto>2</produto>'
    xml +=        '<parcelas>2</parcelas>'
    xml +=    '</forma-pagamento>'

    xml +=    '<url-retorno>null</url-retorno>'
    xml +=    '<autorizar>0</autorizar>'
    xml +=    '<capturar>false</capturar>'
    xml += '</requisicao-autenticacao>'

    t = Pyelo()

    t.enviaXml(xml)


if __name__ == "__main__":
    main()
